package com.jwgf.smarowindingmachine_unity.logic;

import com.jwgf.Half485.fxthreadpool.FxPLCData;
import com.jwgf.Half485.modbusthreadpool.ModbusCommandManager;
import com.jwgf.Half485.modbusthreadpool.PLCData;
import com.jwgf.common.Utility;
import com.jwgf.fault.FaultRecorder;
import com.jwgf.fram.FramManager;
import com.jwgf.group.Group;
import com.jwgf.group.GroupMap;
import com.jwgf.objectbox.ObjectBox;
import com.jwgf.objectbox.SpindleParameter;
import com.jwgf.objectbox.TubeRecord;
import com.jwgf.objectbox.TubeRecord4E;
import com.jwgf.objectbox.TubeRecord_;
import com.jwgf.report.ShiftTimeRule;
import com.jwgf.smarowindingmachine_unity.ui.SmaroWindingMachineActivity;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.objectbox.Box;
import io.reactivex.rxjava3.functions.Consumer;

public class SmaroWindingMachineModBusReadParser {
    private static FramManager fm;
    private static SmaroWindingMachineModBusReadParser instance = null;
    private HashSet<Integer> faultSet = new HashSet<Integer>();

    private static HashMap<Integer, Integer> addressMap;
    private RxMerge2Event<Integer> merge = new RxMerge2Event<Integer>();

    private SmaroWindingMachineModBusReadParser() {
        super();
        merge.getObservable().throttleLast(2, TimeUnit.SECONDS).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                switch (integer) {
                    case 309:
                    case 310:
                    case 313:
                    case 314:
                    case 315:
                    case 316:
                    case 317:
                        Calendar c = Calendar.getInstance();
                        int year = PLCData.getInstance().getHoldingRegister(1, 313);
                        int month = PLCData.getInstance().getHoldingRegister(1, 314);
                        int day = PLCData.getInstance().getHoldingRegister(1, 315);
                        int hour = PLCData.getInstance().getHoldingRegister(1, 316);
                        int minute = PLCData.getInstance().getHoldingRegister(1, 317);
                        int second = 0;
                        c.set(Calendar.YEAR, year);
                        c.set(Calendar.MONTH, month - 1);
                        c.set(Calendar.DAY_OF_MONTH, day);
                        c.set(Calendar.HOUR_OF_DAY, hour);
                        c.set(Calendar.MINUTE, minute);
                        c.set(Calendar.SECOND, second);
                        handleTubeMonitor(PLCData.getInstance().get2HoldingRegister(1, 309));
                        handleTubeMonitor4E(c.getTimeInMillis(), PLCData.getInstance().get2HoldingRegister(1, 309));
                        break;
                }
            }
        });
        fm = FramManager.getInstance();
        EventBus.getDefault().register(this);
    }

    public static SmaroWindingMachineModBusReadParser getInstance() {
        if (instance == null) {
            instance = new SmaroWindingMachineModBusReadParser();
        }
        return instance;
    }

    private static void initAddressMap() {
        if (addressMap == null) {
            addressMap = new HashMap<Integer, Integer>();
            addressMap.put(2 << 16 | 720, 0);
            addressMap.put(2 << 16 | 721, 1);
            addressMap.put(2 << 16 | 722, 2);
            addressMap.put(2 << 16 | 723, 3);
            addressMap.put(2 << 16 | 724, 4);
            addressMap.put(2 << 16 | 725, 5);
            addressMap.put(2 << 16 | 727, 6);
            addressMap.put(2 << 16 | 726, 10);

            addressMap.put(2 << 16 | 113, 250);
            addressMap.put(2 << 16 | 114, 251);
            addressMap.put(2 << 16 | 102, 252);
            addressMap.put(2 << 16 | 103, 252);
            addressMap.put(2 << 16 | 104, 252);
            addressMap.put(2 << 16 | 105, 252);
            addressMap.put(2 << 16 | 106, 252);
            addressMap.put(2 << 16 | 107, 252);
            addressMap.put(2 << 16 | 108, 252);
            addressMap.put(2 << 16 | 111, 252);
            addressMap.put(2 << 16 | 112, 252);
            addressMap.put(2 << 16 | 115, 252);
            addressMap.put(2 << 16 | 116, 252);
            addressMap.put(2 << 16 | 109, 253);


            addressMap.put(4 << 16 | 407, 50);
            addressMap.put(4 << 16 | 403, 51);
            addressMap.put(4 << 16 | 404, 52);
            addressMap.put(4 << 16 | 406, 53);
            addressMap.put(4 << 16 | 405, 54);
            addressMap.put(4 << 16 | 408, 55);
            addressMap.put(4 << 16 | 402, 56);
            addressMap.put(4 << 16 | 400, 57);
            addressMap.put(4 << 16 | 401, 58);
            addressMap.put(4 << 16 | 409, 59);
            addressMap.put(4 << 16 | 416, 60);
            addressMap.put(4 << 16 | 415, 61);
            addressMap.put(4 << 16 | 417, 62);
            addressMap.put(4 << 16 | 420, 63);
            addressMap.put(4 << 16 | 411, 64);

            addressMap.put(4 << 16 | 300, 300);
            addressMap.put(4 << 16 | 301, 301);
            addressMap.put(4 << 16 | 302, 302);
            addressMap.put(4 << 16 | 303, 303);
            addressMap.put(4 << 16 | 304, 304);
            addressMap.put(4 << 16 | 305, 307);
            //细络联和大纱库的进管数量
//            addressMap.put(4 << 16 | 311, 320);
            addressMap.put(5 << 16 | 311, 320);

            addressMap.put(4 << 16 | 312, 321);
            addressMap.put(4 << 16 | 313, 322);
            addressMap.put(4 << 16 | 314, 323);
            addressMap.put(4 << 16 | 315, 324);
            addressMap.put(4 << 16 | 316, 325);
            addressMap.put(4 << 16 | 317, 326);
            addressMap.put(4 << 16 | 318, 327);
            addressMap.put(4 << 16 | 319, 330);
            //308,309,310寄存器边界不对齐，无法使用映射，需要特殊处理，详见fxtoModbus()
//            addressMap.put(4 << 16 | 308, 331);
//            addressMap.put(4 << 16 | 309, 331);
//            addressMap.put(4 << 16 | 310, 331);


            addressMap.put(5 << 16 | 412, 100);
            addressMap.put(5 << 16 | 416, 101);
            addressMap.put(5 << 16 | 411, 102);
            addressMap.put(5 << 16 | 409, 103);

            addressMap.put(5 << 16 | 308, 352);
            addressMap.put(5 << 16 | 310, 352);

//            addressMap.put(6 << 16 | 210, 150);
//            addressMap.put(6 << 16 | 211, 151);
//            addressMap.put(6 << 16 | 212, 152);
//            addressMap.put(6 << 16 | 213, 153);
//            addressMap.put(6 << 16 | 214, 154);
//            addressMap.put(6 << 16 | 215, 155);
//            addressMap.put(6 << 16 | 216, 156);
//            addressMap.put(6 << 16 | 224, 157);
//            addressMap.put(6 << 16 | 225, 158);
//            addressMap.put(6 << 16 | 226, 159);
//
//            addressMap.put(6 << 16 | 161, 400);
//            addressMap.put(6 << 16 | 164, 401);
//            addressMap.put(6 << 16 | 166, 402);
//            addressMap.put(6 << 16 | 168, 403);
//            addressMap.put(6 << 16 | 176, 404);
//            addressMap.put(6 << 16 | 177, 405);

            //6号站160,162,163地址无法映射，需要特殊处理


//            addressMap.put(8 << 16 | 2, 200);
//            addressMap.put(8 << 16 | 3, 201);
//            addressMap.put(8 << 16 | 4, 202);
//
//            addressMap.put(8 << 16 | 11, 450);
//            addressMap.put(8 << 16 | 12, 451);
//            addressMap.put(8 << 16 | 13, 452);
//            addressMap.put(8 << 16 | 14, 453);

        }
    }

    @Subscribe
    public void onHoldingRegisterEvent(PLCData.HoldingRegister holding) {
        int addr = holding.addr;
        int value = holding.value;
        int oldValue = holding.oldValue;
        switch (addr) {
            case 252:// 2号PLC故障252
                handlePlc252(2, addr, oldValue, value);
                break;
            case 253:
                handle109Cmd(oldValue, value);
                break;
            case 254:// 2号PLC故障252
                handlePlc254(2, addr, oldValue, value);
                break;
            case 307:// 4号PLC故障 细络联307
                handlePlc4(4, addr, oldValue, value);
                break;
            case 331:// 大纱库
                handlePlc41(4, addr, oldValue, value);
                break;
            case 332:
                handlePlc42(4, addr, oldValue, value);
                break;
            case 352:
                handlePlc5(5, addr, oldValue, value);
                break;
            case 309:
            case 310:
                merge.onNext(addr);
                break;
            case 333:
                handleGroupStart(2, addr, oldValue, value);
                break;
            case 334:
                boolean oldBool = Utility.BitUtils.getBitValue(oldValue, 14);
                boolean bool = Utility.BitUtils.getBitValue(value, 14);
                if (oldBool != bool) {
                    List<Group> groups = GroupMap.getInstance().getGroupList();
                    for (int group = 0; group < groups.size(); ++group) {
                        SpindleParameter parameter = ObjectBox.get().boxFor(SpindleParameter.class).get(groups.get(group).getId());
                        if (parameter.etcFullDischarge.equals("0")) {
                            SmaroWindingMachineActivity.canHandStack.putPriorityCmd(CanCommand.getBus());
                            if (bool) {
                                SmaroWindingMachineActivity.canHandStack.putPriorityCmd(CanCommand.createGroupCmd37(group + 1, 1));
                            } else {
                                SmaroWindingMachineActivity.canHandStack.putPriorityCmd(CanCommand.createGroupCmd37(group + 1, 0));
                            }
                            SmaroWindingMachineActivity.canHandStack.putPriorityCmd(CanCommand.releaseBus());
                        }
                    }
                }
                break;
        }
        // 非故障的处理，直接存Fram
        try {
            fm.putInt(String.valueOf(addr), value);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Subscribe
    public void onDRegisterEvent(FxPLCData.DRegister dRegister) {
        initAddressMap();
        fxToModbus(dRegister);
    }

    //fx转换为modbus后的缓存
    private int plc_252;
    private int plc_307;
    private int plc_331;
    private int plc_332;
    private int plc_352;

    //fx寄存器缓存
    private int fxPlc2_d0109;

    private void fxToModbus(FxPLCData.DRegister dRegister) {
        int key = dRegister.id << 16 | dRegister.addr;

        switch (key) {
            case (2 << 16 | 111): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 1, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 112): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 2, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 115): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 3, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 116): {
                int oldBit = plc_252 & 0x10;
                int newBit = dRegister.value;
                // 三菱plc
                if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.PLC_TYPE, "0").equals("1")) {
                    if (MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("5")
                            || MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("0")) {// 大纱库或人工落纱
                        if (oldBit != 0 && newBit == 0 && fxPlc2_d0109 == 1) {
                            setDofferRun();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOn();
                        } else {
                            setDofferStop();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOff();
                        }

                    }
                }
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 4, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 102): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 8, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 103): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 9, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 104): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 10, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 105): {
                int oldBit = plc_252 & 0x800;
                int newBit = dRegister.value;
                // 三菱plc
                if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.PLC_TYPE, "0").equals("1")) {
                    if (MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("5")
                            || MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("0")) {// 大纱库或人工落纱
                        if (oldBit != 0 && newBit == 0 && fxPlc2_d0109 == 1) {
                            setDofferRun();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOn();
                        } else {
                            setDofferStop();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOff();
                        }

                    }
                }
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 11, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 106): {
                int oldBit = plc_252 & 0x1000;
                int newBit = dRegister.value;
                // 三菱plc
                if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.PLC_TYPE, "0").equals("1")) {
                    if (MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("5")
                            || MachineParameterSharedPreference.getInstance()
                            .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("0")) {// 大纱库或人工落纱
                        if (oldBit != 0 && newBit == 0 && fxPlc2_d0109 == 1) {
                            setDofferRun();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOn();
                        } else {
                            setDofferStop();
                            FunctionSet.getInstance().setAllSpindleAutoRunningOff();
                        }

                    }
                }
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 12, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 107): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 13, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 108): {
                int oldValue = plc_252;
                plc_252 = Utility.BitUtils.setBitValue(plc_252, 14, dRegister.value);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_252;
                reg.oldValue = oldValue;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (2 << 16 | 109): {
                int oldBit = fxPlc2_d0109;
                int newBit = dRegister.value;
                // 三菱plc
                if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.PLC_TYPE, "0").equals("1")) {
                    if (oldBit != 1 && newBit == 1) {
                        setDofferRun();
                        FunctionSet.getInstance().setAllSpindleAutoRunningOn();
                    } else {
                        setDofferStop();
                        FunctionSet.getInstance().setAllSpindleAutoRunningOff();
                    }
                }
                fxPlc2_d0109 = dRegister.value;

            }
            break;
            case (4 << 16 | 305): {
                plc_307 = ((dRegister.value << 8) & 0xff00) | ((dRegister.value >> 8) & 0xff);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.value = plc_307;
                reg.addr = addressMap.get(key);
                onHoldingRegisterEvent(reg);
            }
            break;
            case (4 << 16 | 307): {
                plc_331 = (dRegister.value << 8) | (plc_331 & 0xff);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 331;
                reg.value = plc_331;
                onHoldingRegisterEvent(reg);
            }
            break;
            case (4 << 16 | 308): {
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 0, dRegister.value & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 1, (dRegister.value >> 1) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 2, (dRegister.value >> 2) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 3, (dRegister.value >> 4) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 4, (dRegister.value >> 5) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 5, (dRegister.value >> 7) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 6, (dRegister.value >> 8) & 0x01);
                plc_331 = Utility.BitUtils.setBitValue(plc_331, 7, (dRegister.value >> 11) & 0x01);
                PLCData.HoldingRegister reg1 = new PLCData.HoldingRegister();
                reg1.addr = 331;
                reg1.value = plc_331;
                onHoldingRegisterEvent(reg1);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 8, (dRegister.value >> 14) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 9, (dRegister.value >> 15) & 0x01);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 332;
                reg.value = plc_332;
                onHoldingRegisterEvent(reg);
            }
            break;
            case (4 << 16 | 309): {
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 10, dRegister.value & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 11, (dRegister.value >> 1) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 12, (dRegister.value >> 2) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 13, (dRegister.value >> 3) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 14, (dRegister.value >> 4) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 15, (dRegister.value >> 5) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 0, (dRegister.value >> 6) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 1, (dRegister.value >> 7) & 0x01);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 332;
                reg.value = plc_332;
                onHoldingRegisterEvent(reg);
            }
            break;
            case (4 << 16 | 310): {
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 2, (dRegister.value >> 1) & 0x01);
                plc_332 = Utility.BitUtils.setBitValue(plc_332, 3, (dRegister.value >> 2) & 0x01);
//                plc_332 = Utility.BitUtils.setBitValue(plc_332, 4, (dRegister.value >> 3) & 0x01);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 332;
                reg.value = plc_332;
                onHoldingRegisterEvent(reg);
            }
            break;
            case (5 << 16 | 308): {
                if (((plc_352 & 0x100) == 0 && ((dRegister.value >> 3) & 0x01) == 1)
                        || ((plc_352 & 0x200) == 0 && ((dRegister.value >> 6) & 0x01) == 1)
                        || ((plc_352 & 0x400) == 0 && ((dRegister.value >> 9) & 0x01) == 1)
                        || ((plc_352 & 0x800) == 0 && ((dRegister.value >> 10) & 0x01) == 1)
                        || ((plc_352 & 0x1000) == 0 && ((dRegister.value >> 13) & 0x01) == 1)) {
//                    SmaroWindingMachineActivity.half485Stack
//                            .putPriorityCmd(FxUtils.createWWCmd(4, 415, (short) 1));
                }
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 8, (dRegister.value >> 3) & 0x01);
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 9, (dRegister.value >> 6) & 0x01);
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 10, (dRegister.value >> 9) & 0x01);
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 11, (dRegister.value >> 10) & 0x01);
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 12, (dRegister.value >> 13) & 0x01);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 352;
                reg.value = plc_352;
                onHoldingRegisterEvent(reg);
            }
            break;
            case (5 << 16 | 310): {
                if ((plc_352 & 0x2000) == 0 && dRegister.value == 1) {
//                    SmaroWindingMachineActivity.half485Stack
//                            .putPriorityCmd(FxUtils.createWWCmd(4, 417, (short) 1));
//                    SmaroWindingMachineActivity.half485Stack
//                            .putPriorityCmd(FxUtils.createWWCmd(2, 727, (short) 1));
                } else if ((plc_352 & 0x2000) != 0 && dRegister.value == 0) {
//
                }
                plc_352 = Utility.BitUtils.setBitValue(plc_352, 13, dRegister.value & 0x01);
                PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                reg.addr = 352;
                reg.value = plc_352;
                onHoldingRegisterEvent(reg);
            }
            break;
            default:
                if (addressMap.get(key) != null) {
                    PLCData.HoldingRegister reg = new PLCData.HoldingRegister();
                    reg.addr = addressMap.get(key);
                    reg.value = dRegister.value;
                    onHoldingRegisterEvent(reg);
                }
                break;
        }
    }

    private void handle109Cmd(int oldData, int value) {
        if (value == 0) {
            setDofferStop();
            FunctionSet.getInstance().setAllSpindleAutoRunningOff();
            setDofferStop();
        } else {
            if (oldData == 0) {
                setDofferRun();
                FunctionSet.getInstance().setAllSpindleAutoRunningOn();
                setDofferRun();
            }
        }
    }

    public void handleTubeMonitor(int newValue) {
        if ((newValue & 0xffff0000) == 0)
            return;
        Box<TubeRecord> box = ObjectBox.get().boxFor(TubeRecord.class);
        TubeRecord record = box.query().equal(TubeRecord_.start, Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime()))
                .equal(TubeRecord_.tubeNum, newValue).build().findFirst();
        if (record == null) {
            record = new TubeRecord();
            record.start = Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime());
            record.tubeNum = newValue;
        }
        record.count++;
        record.lastTime = Calendar.getInstance().getTimeInMillis();
        box.put(record);
    }

    public void handleTubeMonitor4E(long time, int newValue) {
        if ((newValue & 0xffff0000) == 0)
            return;
        Box<TubeRecord4E> box = ObjectBox.get().boxFor(TubeRecord4E.class);
        TubeRecord4E record = new TubeRecord4E();
        record.start = Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime());
        record.tubeNum = newValue;
        record.enterTime = time;
        box.put(record);
    }

    public void handleGroupStart(int id, int addr, int oldValue, int newValue) {
        for (int i = 8; i < 16; ++i) {
            int oldBit = (oldValue >> i) & 1;
            int newBit = (newValue >> i) & 1;
//            if (i == 7) { //第9锭节启动
//                if (oldBit == 0 && newBit == 1) {
//                    FunctionSet.getInstance().setGroupAutoRunningOn(9);
//                }
//            } else {
            if (oldBit == 0 && newBit == 1) {
                FunctionSet.getInstance().setGroupAutoRunningOn(i - 8 + 1);
            }
//            }

        }
    }

    public void handlePlc252(int id, int addr, int oldValue, int newValue) {
        for (int i = 0; i < 16; i++) {
            if (i == 0 || i == 5) {

            } else {
                int oldBit = (oldValue >> i) & 0x01;
                int newBit = (newValue >> i) & 0x01;
                int code = (id << 24) | (addr << 8) | i;
                if (i == 13 || i == 14) {
                    if (newBit == 0 && oldBit == 1) {// 报警变化从1为0之后给单锭初始化
                        SmaroWindingMachineActivity.canHandStack.putPriorityCmd(CanCommand.initAll());
                        faultGenerate(id, code, false);
                    } else if (newBit == 1 && oldBit == 0) {
                        faultGenerate(id, code, true);
                    }
                } else if (i == 3) {
                    if (newBit == 0 && oldBit == 1) {// 管纱输送状态0，小车状态开启
                        SmaroWindingMachineActivity.canHandStack.putPriorityCmd(
                                CanCommand.createSingle(0x9F, 0x75, 510, 0, 0));
                    } else if (newBit == 1 && oldBit == 0) {// 管纱输送状态1，小车状态停止
                        SmaroWindingMachineActivity.canHandStack.putPriorityCmd(
                                CanCommand.createSingle(0x9F, 0x75, 510, 1, 0));
                    }
                } else {
                    if (newBit == 1 && oldBit == 0) {
                        faultGenerate(id, code, true);
                    } else if (newBit == 0 && oldBit == 1) {
                        faultGenerate(id, code, false);
                    }
                }
            }
        }
    }

    public void handlePlc254(int id, int addr, int oldValue, int newValue) {
        for (int i = 0; i < 16; i++) {
            if (i == 0 || i == 1 || i == 2 || (i >= 8)) {
                int oldBit = (oldValue >> i) & 0x01;
                int newBit = (newValue >> i) & 0x01;
                int code = (id << 24) | (addr << 8) | i;
                if (newBit == 1 && oldBit == 0) {
                    faultGenerate(id, code, true);
                } else if (newBit == 0 && oldBit == 1) {
                    faultGenerate(id, code, false);
                }
            }
            // 509.3
            if (i == 3) {
                int newBit = (newValue >> i) & 0x01;
                SmaroWindingMachineActivity.canHandStack.putPriorityCmd(
                        MachineParameterSharedPreference.getInstance().createCanCmd75(0x75, 0x01, 555, String.valueOf(newBit)));

            }
        }
    }

    public void handlePlc4(int id, int addr, int oldValue, int newValue) {
        for (int i = 0; i < 16; i++) {
            int oldBit = (oldValue >> i) & 0x01;
            int newBit = (newValue >> i) & 0x01;
            int code = (id << 24) | (addr << 8) | i;
            if (MachineParameterSharedPreference.getInstance()
                    .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("3")) {// 细络联
                if (i >= 8 && i <= 19) {
                    if (newBit == 0 && oldBit == 1) {
                        faultGenerate(id, code, false);
                    } else if (newBit == 1 && oldBit == 0) {
                        faultGenerate(id, code, true);
                    }
                }
            }
        }

    }


    //大紗庫機型331
    public void handlePlc41(int id, int addr, int oldValue, int newValue) {
        for (int i = 0; i < 8; i++) {
            if (i == 2 || i == 7)
                continue;
            int oldBit = (oldValue >> i) & 0x01;
            int newBit = (newValue >> i) & 0x01;
            int code = (id << 24) | (addr << 8) | i;
            if (newBit == 1 && oldBit == 0) {
                faultGenerate(id, code, true);
            } else if (newBit == 0 && oldBit == 1) {
                faultGenerate(id, code, false);
            }
        }
    }

    //大紗庫機型332
    public void handlePlc42(int id, int addr, int oldValue, int newValue) {
        for (int i = 0; i < 16; i++) {
            if ((i == 5) || (i == 6)) {

            } else {
                int oldBit = (oldValue >> i) & 0x01;
                int newBit = (newValue >> i) & 0x01;
                int code = (id << 24) | (addr << 8) | i;
                if (i == 4) {
                    if (newBit == 1 && oldBit == 0) {
                        byte[] datai = new byte[2];
                        datai[0] = (byte) ((1 & 0xff00) >> 8);
                        datai[1] = (byte) (1 & 0xff);
                        ModbusCommandManager.getInstance()
                                .putPriorityCmd(CommandGenerator.createWriteCommand((byte) 1, 6, datai));// 停止平皮带
                        // 727
                        faultGenerate(id, code, true);
                    } else if (newBit == 0 && oldBit == 1) {
                        byte[] datai = new byte[2];
                        datai[0] = (byte) ((0 & 0xff00) >> 8);
                        datai[1] = (byte) (0 & 0xff);
                        ModbusCommandManager.getInstance()
                                .putPriorityCmd(CommandGenerator.createWriteCommand((byte) 1, 6, datai));// 727
                        faultGenerate(id, code, false);
                    }
                } else {
                    if (newBit == 1 && oldBit == 0) {
                        faultGenerate(id, code, true);
                    } else if (newBit == 0 && oldBit == 1) {
                        faultGenerate(id, code, false);
                    }
                }
            }
        }
    }


    public void handlePlc5(int id, int addr, int oldValue, int newValue) {
        for (int i = 8; i < 16; i++) {
            if (i == 13) {
                continue;
            }
            int oldBit = (oldValue >> i) & 0x01;
            int newBit = (newValue >> i) & 0x01;
            int code = (id << 24) | (addr << 8) | i;
            if (newBit == 1 && oldBit == 0) {
                faultGenerate(id, code, true);
            } else if (newBit == 0 && oldBit == 1) {
                faultGenerate(id, code, false);
            }
        }
    }

    public void faultGenerate(int id, int code, boolean isStart) {
        boolean isCommError = false;

        FaultRecorder fr = FaultRecorder.getInstance();
        int faultType = -1;
        switch (id) {
            case 0:
                int key = (0xffff << 8) | 0xff;
                if (code == key) {
                    isCommError = true;
                }
            case 2:
                faultType = FaultRecorder.MACHINE_FAULT_TYPE;
                break;
            case 4:
            case 5:
                faultType = FaultRecorder.CBF_FAULT_TYPE;
                break;
            default:
                break;
        }
        synchronized (faultSet) {
            if (isStart) {
                if (!faultSet.contains(code)) {
                    faultSet.add(code);
                }
                if (!isCommError) {
                    fr.startFaultRecord(faultType, code);
                }
            } else {
                if (faultSet.contains(code)) {
                    faultSet.remove(code);
                }
                if (!isCommError) {
                    fr.stopFaultRecord(faultType, code);
                }
            }
        }
    }

    public ArrayList<Integer> getCurrentFaultList() {
        ArrayList<Integer> curFaultList = new ArrayList<Integer>();
        synchronized (faultSet) {
            curFaultList.addAll(faultSet);
        }
        return curFaultList;
    }

    public void setDofferRun() {
        SmaroWindingMachineActivity.canHandStack
                .putPriorityCmd(MachineParameterSharedPreference.getInstance().createCanCmd75(0x75, 0x01, 502, "1"));
    }

    public void setDofferStop() {
        SmaroWindingMachineActivity.canHandStack
                .putPriorityCmd(MachineParameterSharedPreference.getInstance().createCanCmd75(0x75, 0x01, 502, "0"));
    }

}
